﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using ANZ_AIM_BLL;
using ANZ_AIM_FRAMEWORK;
using ANZ_AIM_BLL.Model;
using ANZ_AIM_GUI.Utils;
using System.Text.RegularExpressions;
using System.IO;
using log4net;

namespace ANZ_AIM_GUI
{
    public partial class frmCandidateUpload : Form
    {
        //log4net
        private static readonly ILog logger = LogManager.GetLogger(typeof(frmCandidateUpload));

        public List<Candidate> candidateList = new List<Candidate>();
        protected AppParam appParam = AppParam.Instance;

        public frmCandidateUpload()
        {
            try
            {
                InitializeComponent();
                LoadComponent();
                LoadData();
            }
            catch (Exception ex) { throw ex; }
        }

        private void LoadComponent()
        {
            try
            {
                this.btnOpenFile.Enabled = appParam.Role.Contains(User.ROLE_EXECUTER);
                this.btnUpload.Enabled = appParam.Role.Contains(User.ROLE_EXECUTER);
                this.txtFileName.Enabled = appParam.Role.Contains(User.ROLE_EXECUTER);
            }
            catch (Exception ex) { throw ex; }
        }
        private void LoadData()
        {
            try
            {
                BatchFileUploadBLL batchFileUploadBl = new BatchFileUploadBLL();
                DataTable dt = batchFileUploadBl.GetBatchFileByStatus(Constant.NEED_TO_VERIFY);
                dt.Merge(batchFileUploadBl.GetBatchFileByStatus(Constant.NEED_TO_UPDATE));

                foreach (DataRow item in dt.Rows)
                {
                    item["Status"] = Constant.BatchStatusMap[item["Status"].ToString()];
                }


                dgvData.DataSource = null;
                dgvData.Columns.Clear();
                dgvData.DataSource = MiscHelper.ChangeColumnNameByMap(dt, Constant.BatchFileUploadTableMap);
                dgvData.AutoResizeColumns();

                dgvData.Columns["Total Record"].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                this.dgvData.Sort(this.dgvData.Columns["Created Date"], ListSortDirection.Descending);
            }
            catch (Exception ex) { throw ex; }
        }

        //Check max file size when upload
        private bool checkFileSizeUpload(string filePath)
        {
            try
            {
                ConfigurationBLL configurationBLL = new ConfigurationBLL();
                Configuration configuration = configurationBLL.GetByKey(Configuration.MAX_FILE_SIZE_UPLOAD);
                FileInfo fileInfo = new FileInfo(filePath);
                string maxFileSize = configuration.ConfigValue;
                if (fileInfo.Length / 1024 > Convert.ToDouble(maxFileSize))
                {
                    MessageBox.Show("The file size is greater than Maximum, please select another file.", Constant.SYS_INFORMATION, MessageBoxButtons.OK, MessageBoxIcon.Information);
                    return false;
                }
                return true;
            }
            catch (Exception ex) { throw ex; }
        }

        #region Action
        private void btnOpenFile_Click(object sender, EventArgs e)
        {
            try
            {
                OpenFileDialog ExcelDialog = new OpenFileDialog();
                ExcelDialog.Filter = "Excel Files|*.xls;*.xlsx;*.xlsm";
                ExcelDialog.InitialDirectory = appParam.PathFile;
                ExcelDialog.Title = "Select your file excel";
                if (ExcelDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    txtFileName.Text = ExcelDialog.FileName;
                    txtFileName.ReadOnly = true;

                    var lastPath = txtFileName.Text;
                    lastPath = lastPath.Substring(0, lastPath.LastIndexOf("\\"));
                    if (appParam.PathFile != lastPath)
                        appParam.PathFile = lastPath;
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.InnerException == null ? ex.Message : ex.InnerException.Message, Constant.SYS_ERROR, MessageBoxButtons.OK);
                logger.Error(ex.Message + " - " + ex.StackTrace);
            }
        }
        private void btnUpload_Click(object sender, EventArgs e)
        {
            var msg = String.Empty;
            try
            {
                if (string.IsNullOrEmpty(txtFileName.Text.Trim()))
                {
                    MessageBox.Show(Constant.EMPTY_FILE, Constant.SYS_ERROR, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    txtFileName.Focus();
                    return;
                }

                //Check file size       
                if (checkFileSizeUpload(txtFileName.Text.Trim()) == false)
                    return;

                //clear list when upload new file
                candidateList.Clear();

                //bind datarow to list 
                DataTable dtData = NPOIHelper.ImportExceltoDt(txtFileName.Text.Trim(), 0, 2);
                foreach (DataRow dr in dtData.Rows)
                {
                    PackObject(dr);
                }

                int total = candidateList.Count;

                string message = "";
                List<Candidate> listTemp = new List<Candidate>();

                //validate candidate
                ValidateCandidateUpload(ref message, ref listTemp);

                if (candidateList != null && candidateList.Count > 0)
                {

                    //insert Candidate DB
                    CandidateBLL candidateBll = new CandidateBLL();
                    bool flag = candidateBll.Save(candidateList);

                    if (flag == false)
                    {
                        MessageBox.Show("Duplicate Record", Constant.SYS_ERROR, MessageBoxButtons.OK, MessageBoxIcon.Error);
                        return;
                    }

                    //insert BatchFileUpload DB
                    int IDFileBatchUpload = 0;
                    BatchFileUploadBLL batchFileBll = new BatchFileUploadBLL();
                    string[] s = txtFileName.Text.Trim().Split('\\');
                    //batchFileBll.Save(new BatchFileUpload() { CreatedDate = MiscHelper.DateTimeToShort(DateTime.Now), FileName = s[s.Length - 1], TotalRecord = candidateList.Count.ToString(), Status = Constant.NEED_TO_VERIFY }, ref IDFileBatchUpload); //22Jan2015
                    batchFileBll.Save(new BatchFileUpload() { CreatedDate = MiscHelper.DateTimeToShort(DateTime.Now), FileName = s[s.Length - 1], TotalRecord = candidateList.Count.ToString(), Status = Constant.NEED_TO_UPDATE }, ref IDFileBatchUpload); //22Jan2015 Change status to always NEEDTOUPDATE

                    //update batchfileid 
                    foreach (Candidate can in candidateList)
                    {
                        can.BatchFileID = IDFileBatchUpload.ToString();
                    }
                    candidateBll.UpdateBatchFileID(candidateList);

                    //load lai du lieu
                    LoadData();
                }

                //show infor
                string info = "Candidates are uploaded: \n";
                info += "Successfull: " + candidateList.Count.ToString() + " \n";
                info += "Fail: " + listTemp.Count.ToString() + message + "\n";
                info += "Please see the uploaded file for details.";

                if (listTemp != null && listTemp.Count > 0)
                {
                    //export excel with error record
                    ExportExcel(txtFileName.Text.Trim(), dtData, listTemp);
                }
                MessageBox.Show(info, Constant.SYS_INFORMATION, MessageBoxButtons.OK, MessageBoxIcon.Information);
                msg = String.Format("{0}: {1}", Constant.SYS_MSG_CANDIDATE_UPLOAD, txtFileName.Text.Trim());
            }
            catch (Exception ex)
            {
                MessageBox.Show(Constant.IMPORT_WRONG_FILE, Constant.SYS_ERROR, MessageBoxButtons.OK, MessageBoxIcon.Error);
                logger.Error(ex.Message + " - " + ex.StackTrace);
                return;
            }

            try
            {
                if (!String.IsNullOrEmpty(msg))
                {
                    LogBLL logBll = new LogBLL();
                    logBll.Description = msg;
                    logBll.Log(this.FindForm(), appParam.UserName);
                }
            }
            catch { }
        }
        private void dgvData_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                int selectedRowCount = dgvData.Rows.GetRowCount(DataGridViewElementStates.Selected);
                if (selectedRowCount > 0)
                {
                    DataRow dr = ((DataRowView)dgvData.SelectedRows[0].DataBoundItem).Row;
                    string batchFileID = dr[0].ToString();
                    CandidateBLL candidateBll = new CandidateBLL();
                    DataTable dt = candidateBll.GetByBatchFileID(batchFileID);

                    dgvCandidate.DataSource = null;
                    dgvCandidate.Columns.Clear();
                    dgvCandidate.DataSource = MiscHelper.ChangeColumnNameByMap(dt, Constant.CandidatesTableMap);
                    dgvCandidate.AutoResizeColumns();

                    //frmDataUpload frmDataUpload = new frmDataUpload(dr[0].ToString());
                    //frmDataUpload.ShowDialog(this);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.InnerException == null ? ex.Message : ex.InnerException.Message, Constant.SYS_ERROR, MessageBoxButtons.OK);
                logger.Error(ex.Message + " - " + ex.StackTrace);
            }
        }
        private void dgvCandidate_MouseDoubleClick(object sender, MouseEventArgs e)
        {
            try
            {
                if (appParam.Role.Contains(User.ROLE_EXECUTER))
                {
                    int selectedRowCount = dgvCandidate.Rows.GetRowCount(DataGridViewElementStates.Selected);
                    if (selectedRowCount > 0)
                    {
                        DataRow dr = ((DataRowView)dgvCandidate.SelectedRows[0].DataBoundItem).Row;
                        string CVCode = dr[0].ToString();

                        frmCandidateUpdateInfo frmCandidateUpdate = new frmCandidateUpdateInfo(CVCode);
                        frmCandidateUpdate.ShowDialog(this);
                    }
                }

                //22Jan2015 BEGIN Check Candidate info for changing status of Batch File
                int NumberOfMissInfoCandidate = 0;
                string CurrentSelectedBatchFileID = "0";
                CandidateBLL candidateBll = new CandidateBLL();
                foreach (DataGridViewRow item in dgvCandidate.Rows)
                {
                    Candidate candidate = candidateBll.GetById(item.Cells[0].Value.ToString());
                    CurrentSelectedBatchFileID = candidate.BatchFileID;
                    if (candidate.Category.Equals("") || candidate.ProductCategory.Equals("") ||
                        candidate.Product.Equals("") || candidate.TeamLeaderCode.Equals("") ||
                        candidate.Status.Equals("") || candidate.FingerID.Equals("") ||
                        candidate.PersonalTaxCode.Equals("") || candidate.ContractType.Equals("") ||
                        candidate.ContractTerm.Equals("") || candidate.ContractorName.Equals("") ||
                        candidate.BankAccount.Equals("") || candidate.BankBranchAddress.Equals("") ||
                        candidate.BankName.Equals("") || candidate.FillingRefCode.Equals("") ||
                        candidate.ProfressiveTarget.Equals("") 
                        )
                    {
                        NumberOfMissInfoCandidate++;
                    }
                }
                if (NumberOfMissInfoCandidate.Equals(0))
                {
                    new BatchFileUploadBLL().UpdateStatus(CurrentSelectedBatchFileID, Constant.NEED_TO_VERIFY);
                }
                LoadData();

                //Refresh Candidate grid after update info
                DataTable dt = candidateBll.GetByBatchFileID(CurrentSelectedBatchFileID);
                dgvCandidate.DataSource = null;
                dgvCandidate.Columns.Clear();
                dgvCandidate.DataSource = MiscHelper.ChangeColumnNameByMap(dt, Constant.CandidatesTableMap);
                dgvCandidate.AutoResizeColumns();
                //22Jan2015 END Check Candidate info for changing status of Batch File
            }
            catch (Exception ex)
            {
                MessageBox.Show(this, ex.InnerException == null ? ex.Message : ex.InnerException.Message, Constant.SYS_ERROR, MessageBoxButtons.OK);
                logger.Error(ex.Message + " - " + ex.StackTrace);
            }
        }
        #endregion

        private bool ValidateCandidateUpload(ref string message, ref List<Candidate> listTemp)
        {
            try
            {
                CandidateBLL candidateBll = new CandidateBLL();

                listTemp.Clear();
                message = "(ID: ";
                //check exists record                      
                foreach (Candidate can in candidateList)
                {
                    bool flag = candidateBll.CheckCandidateExist(can.CVCode, can.IDNumber);
                    if (flag)
                    {
                        message += can.IDNumber + ",";
                        listTemp.Add(can);
                    }
                }

                //check negative list 
                foreach (Candidate can in candidateList)
                {
                    bool flag = candidateBll.CheckNegativeList(can.CVCode);
                    if (flag)
                    {
                        message += can.IDNumber + ",";
                        listTemp.Add(can);
                    }
                }

                message = message.Trim().TrimEnd(',') + ")";

                //remove exists record
                candidateList = candidateList.Except(listTemp).ToList();

                return true;
            }
            catch (Exception ex) { throw ex; }
        }
        private void PackObject(DataRow drData)
        {
            try
            {
                Candidate candidate = new Candidate();
                candidate.CVCode = drData["CV Code"].ToString();
                candidate.Channel = drData["Channel"].ToString();
                candidate.Team = drData["Team"].ToString();
                candidate.FullName_E = drData["FullName_E"].ToString();
                candidate.FullName_V = drData["FullName_V"].ToString();
                candidate.CellPhone = drData["CellPhone"].ToString();
                candidate.DateOfBirth = Convert.ToDateTime(drData["Date Of Birth"] != null ? drData["Date Of Birth"] : (DateTime?)null);
                candidate.College = drData["College"].ToString();
                candidate.Qualification = drData["Qualification"].ToString();
                candidate.IDNumber = drData["ID Number"].ToString();
                candidate.IssuedDate = Convert.ToDateTime(drData["Issued Date"] != null ? drData["Issued Date"] : (DateTime?)null);
                candidate.IssuedPlace = drData["Issued Place"].ToString();
                candidate.PermanentAddress = drData["Permanent Address"].ToString();
                candidate.Interviewer = drData["Interviewer"].ToString();
                candidate.InterviewDate = Convert.ToDateTime(drData["Interview Date"] != null ? drData["Interview Date"] : (DateTime?)null);
                candidate.TrainingCallStatus = drData["Training Call Status"].ToString();
                candidate.TrainingCallStatusRemarks = drData["Training Call Status Remarks"].ToString();

                candidate.CICSanctionDeliveryDate = Convert.ToDateTime(drData["CIC Sanction Delivery Date"] != null ? drData["CIC Sanction Delivery Date"] : (DateTime?)null);
                candidate.CICSanctionDelivererName = drData["CIC Sanction Deliverer Name"].ToString();
                candidate.CICResult = drData["CIC Result"].ToString();
                candidate.SanctionResult = drData["Sanction Result"].ToString();
                candidate.PECCheckResult = drData["PEC Check Result"].ToString();
                candidate.PECRemarks = drData["PEC Remarks"].ToString();

                candidate.TrainingBatch = drData["Training Batch"].ToString();
                candidate.TrainingDate = Convert.ToDateTime(drData["Training Date"] != null ? drData["Training Date"] : (DateTime?)null);
                candidate.TrainerName = drData["Trainer Name"].ToString();
                candidate.TrainingAttendance = drData["Training Attendance"].ToString();
                candidate.TrainingAttendanceRemarks = drData["Training Attendance Remarks"].ToString();
                candidate.ReTest = drData["Re Test"].ToString();
                candidate.ReTestRequirement = drData["Re Test Requirement"].ToString();
                candidate.TrainingResult = drData["Training Result"].ToString();

                candidate.OBEligible = drData["OBEligible"].ToString();
                candidate.DocumentCompletion = drData["Document Completion"].ToString();
                candidate.DocumentIncompletionRemarks = drData["Document Incompletion Remarks"].ToString();
                candidate.PCReceiptSubmissionDate = Convert.ToDateTime(drData["PC Receipt Submission Date"] != null ? drData["PC Receipt Submission Date"] : (DateTime?)null);
                candidate.PCReportSubmissionDate = Convert.ToDateTime(drData["PC Report Submission Date"] != null ? drData["PC Report Submission Date"] : (DateTime?)null);

                candidate.HiringManagerName = drData["Hiring Manager Name"].ToString();
                candidate.HiringManagerAcknowledgeDate = Convert.ToDateTime(drData["Hiring Manager Acknowledge Date"] != null ? drData["Hiring Manager Acknowledge Date"] : (DateTime?)null);
                candidate.DelegateApproverName = drData["Delegate Approver Name"].ToString();
                candidate.ApprovingDate = Convert.ToDateTime(drData["Approving Date"] != null ? drData["Approving Date"] : (DateTime?)null);
                candidate.OnBoarding = drData["OnBoarding"].ToString();
                candidate.OnBoardingRemarks = Convert.ToDateTime(drData["OnBoarding Remarks"] != null ? drData["OnBoarding Remarks"] : (DateTime?)null);
                candidate.CICSanctionRequestDate = Convert.ToDateTime(drData["CIC Sanction RequestDate"] != null ? drData["CIC Sanction RequestDate"] : (DateTime?)null);
                candidate.TrainingResultCC = drData["Training Result CC"].ToString();
                candidate.CheckChannel = drData["Check Channel"].ToString();

                candidateList.Add(candidate);
            }
            catch (Exception ex) { throw ex; }
        }
        private void ExportExcel(string fileName, DataTable dtSource, List<Candidate> listTemp)
        {
            try
            {
                DataTable DtTemp = ConvertToDataTable<Candidate>(listTemp);
                NPOIHelper.ExportCandidateWithError(dtSource, DtTemp, "CANDIDATE", fileName);
            }
            catch (Exception ex) { throw ex; }
        }

        public DataTable ConvertToDataTable<T>(List<T> data)
        {
            try
            {
                PropertyDescriptorCollection properties =
                   TypeDescriptor.GetProperties(typeof(T));
                DataTable table = new DataTable();
                foreach (PropertyDescriptor prop in properties)
                    table.Columns.Add(prop.Name, Nullable.GetUnderlyingType(prop.PropertyType) ?? prop.PropertyType);
                foreach (T item in data)
                {
                    DataRow row = table.NewRow();
                    foreach (PropertyDescriptor prop in properties)
                        row[prop.Name] = prop.GetValue(item) ?? DBNull.Value;
                    table.Rows.Add(row);
                }
                return table;
            }
            catch (Exception ex) { throw ex; }
        }

        private void frmCandidateUpload_Load(object sender, EventArgs e)
        {

        }
    }
}
